using System;
using System.Collections;
using System.Collections.Generic;
using TestCases.CompareAssert.Core.Comparers.Interfaces;
using TestCases.CompareAssert.Core.Interfaces;

namespace TestCases.CompareAssert.Core.Comparers.Adapters
{
    public class ComparerAdapter : IObjectComparer
    {
        private readonly IComparer _comparer;

        public ComparerAdapter(IComparer comparer)
        {
            _comparer = comparer;
        }

        public string Name
        {
            get { return "ComparerAdapter"; }
        }

        public IResultBuilder Compare(ICompareContext context)
        {
            try
            {
                return this.IsBoolResult(_comparer.Compare(context.LValue, context.RValue) == 0, context);
            }
            catch (ArgumentException)
            {                
            }
            catch (InvalidCastException)
            {                
            }
            return this.IsNotApplicable(context);
        }
    }

    public class ComparerAdapter<T> : IObjectComparer
    {
        private readonly IComparer<T> _comparer;

        public ComparerAdapter(IComparer<T> comparer)
        {
            _comparer = comparer;
        }

        public string Name
        {
            get { return "ComparerAdapter"; }
        }

        public IResultBuilder Compare(ICompareContext context)
        {
            if (!(context.LValue is T))
            {
                return this.IsNotApplicable(context).Left.IsNot<T>();
            }
            if (!(context.RValue is T))
            {
                return this.IsNotApplicable(context).Right.IsNot<T>();
            }
            return this.IsBoolResult(_comparer.Compare((T) context.LValue, (T) context.RValue) == 0, context);
        }
    }
}